package com.umeox.moto.common.log;

import android.util.Log;

import com.umeox.moto.common.BuildConfig;
import com.umeox.moto.common.utils.StringUtils;

import java.util.Locale;

public class LogUtils {

    public static void i(String tag, String msg) {
        log(Log.INFO, tag, msg);
    }

    public static void v(String tag, String msg) {
        log(Log.VERBOSE, tag, msg);
    }

    public static void d(String tag, String msg) {
        log(Log.DEBUG, tag, msg);
    }

    public static void w(String tag, String msg) {
        log(Log.WARN, tag, msg);
    }

    public static void e(String tag, String msg) {
        log(Log.ERROR, tag, msg);
    }

    public static void i(String msg) {
        StackTraceElement caller = getTargetStackTraceElement();
        String tag = generateTag(caller);
        i(tag, msg);
    }

    public static void v(String msg) {
        StackTraceElement caller = getTargetStackTraceElement();
        String tag = generateTag(caller);
        v(tag, msg);
    }

    public static void d(String msg) {
        StackTraceElement caller = getTargetStackTraceElement();
        String tag = generateTag(caller);
        d(tag, msg);
    }

    public static void w(String msg) {
        StackTraceElement caller = getTargetStackTraceElement();
        String tag = generateTag(caller);
        w(tag, msg);
    }

    public static void e(String msg) {
        StackTraceElement caller = getTargetStackTraceElement();
        String tag = generateTag(caller);
        e(tag, msg);
    }

    private static StackTraceElement getTargetStackTraceElement() {
        StackTraceElement targetStackTrace = null;
        boolean shouldTrace = false;
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement stackTraceElement : stackTrace) {
            boolean isLogMethod = stackTraceElement.getClassName().equals(LogUtils.class.getName());
            if (shouldTrace && !isLogMethod) {
                targetStackTrace = stackTraceElement;
                break;
            }
            shouldTrace = isLogMethod;
        }
        return targetStackTrace;
    }

    private static String generateTag(StackTraceElement caller) {
        String tag;
        String callerClazzName = caller.getClassName();
        callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
        if (BuildConfig.DEBUG) {
            tag = "%s.%s(L:%d)";
            tag = String.format(Locale.getDefault(), tag, callerClazzName, caller.getMethodName(), caller.getLineNumber());
        } else {
            tag = "%s.%s";
            tag = String.format(Locale.getDefault(), tag, callerClazzName, caller.getMethodName());
        }
        return tag;
    }

    private static void log(int priority, String tag, String message) {
        if (priority == Log.VERBOSE) {
            return;
        }
        tag = StringUtils.isEmpty(tag) ? generateTag(getTargetStackTraceElement()) : tag;
        int segmentSize = 3 * 1024;
        long length = message.length();
        if (length <= segmentSize) {// 长度小于等于限制直接打印
            println(priority, tag, message);
        } else {
            while (message.length() > segmentSize) {// 循环分段打印日志
                String logContent = message.substring(0, segmentSize);
                println(priority, tag, logContent);
                message = message.replace(logContent, "");
            }
            println(priority, tag, message);// 打印剩余日志
        }
    }

    private static void println(int priority, String tag, String logMessage) {
        switch (priority) {
            case Log.VERBOSE:
                Log.v(tag, logMessage);
                break;
            case Log.DEBUG:
                Log.d(tag, logMessage);
                break;
            case Log.INFO:
                Log.i(tag, logMessage);
                break;
            case Log.WARN:
                Log.w(tag, logMessage);
                break;
            case Log.ERROR:
                Log.e(tag, logMessage);
                break;
        }
    }
}
